/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "v1_0/user_auth_types.h"
#include <hdf_log.h>
#include <securec.h>

namespace OHOS {
namespace HDI {
namespace UserAuth {
namespace V1_0 {

bool ExecutorRegisterInfoBlockMarshalling(OHOS::MessageParcel& data, const ExecutorRegisterInfo& dataBlock)
{
    if (!data.WriteUint32((uint32_t)dataBlock.authType)) {
        HDF_LOGE("%{public}s: write dataBlock.authType failed!", __func__);
        return false;
    }

    if (!data.WriteUint32((uint32_t)dataBlock.executorRole)) {
        HDF_LOGE("%{public}s: write dataBlock.executorRole failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.executorSensorHint)) {
        HDF_LOGE("%{public}s: write dataBlock.executorSensorHint failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.executorMatcher)) {
        HDF_LOGE("%{public}s: write dataBlock.executorMatcher failed!", __func__);
        return false;
    }

    if (!data.WriteUint32((uint32_t)dataBlock.esl)) {
        HDF_LOGE("%{public}s: write dataBlock.esl failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.publicKey.size())) {
        HDF_LOGE("%{public}s: write dataBlock.publicKey.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.publicKey) {
        if (!data.WriteUint8(it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }
    return true;
}

bool ExecutorRegisterInfoBlockUnmarshalling(OHOS::MessageParcel& data, ExecutorRegisterInfo& dataBlock)
{
    dataBlock.authType = (AuthType)data.ReadUint32();
    dataBlock.executorRole = (ExecutorRole)data.ReadUint32();
    dataBlock.executorSensorHint = data.ReadUint32();
    dataBlock.executorMatcher = data.ReadUint32();
    dataBlock.esl = (ExecutorSecureLevel)data.ReadUint32();

    uint32_t publicKeySize = data.ReadUint32();
    dataBlock.publicKey.reserve(publicKeySize);
    for (uint32_t i0 = 0; i0 < publicKeySize; ++i0) {
        uint8_t value0 = data.ReadUint8();
        dataBlock.publicKey.push_back(value0);
    }
    return true;
}

bool ExecutorInfoBlockMarshalling(OHOS::MessageParcel& data, const ExecutorInfo& dataBlock)
{
    if (!data.WriteUint64(dataBlock.executorIndex)) {
        HDF_LOGE("%{public}s: write dataBlock.executorIndex failed!", __func__);
        return false;
    }

    if (!ExecutorRegisterInfoBlockMarshalling(data, dataBlock.info)) {
        HDF_LOGE("%{public}s: write dataBlock.info failed!", __func__);
        return false;
    }
    return true;
}

bool ExecutorInfoBlockUnmarshalling(OHOS::MessageParcel& data, ExecutorInfo& dataBlock)
{
    dataBlock.executorIndex = data.ReadUint64();

    if (!ExecutorRegisterInfoBlockUnmarshalling(data, dataBlock.info)) {
        HDF_LOGE("%{public}s: read dataBlock.info failed!", __func__);
        return false;
    }
    return true;
}

bool ScheduleInfoBlockMarshalling(OHOS::MessageParcel& data, const ScheduleInfo& dataBlock)
{
    if (!data.WriteUint64(dataBlock.scheduleId)) {
        HDF_LOGE("%{public}s: write dataBlock.scheduleId failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.templateIds.size())) {
        HDF_LOGE("%{public}s: write dataBlock.templateIds.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.templateIds) {
        if (!data.WriteUint64(it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }

    if (!data.WriteUint32((uint32_t)dataBlock.authType)) {
        HDF_LOGE("%{public}s: write dataBlock.authType failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.executorMatcher)) {
        HDF_LOGE("%{public}s: write dataBlock.executorMatcher failed!", __func__);
        return false;
    }

    if (!data.WriteUint32((uint32_t)dataBlock.scheduleMode)) {
        HDF_LOGE("%{public}s: write dataBlock.scheduleMode failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.executors.size())) {
        HDF_LOGE("%{public}s: write dataBlock.executors.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.executors) {
        if (!ExecutorInfoBlockMarshalling(data, it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }
    return true;
}

bool ScheduleInfoBlockUnmarshalling(OHOS::MessageParcel& data, ScheduleInfo& dataBlock)
{
    dataBlock.scheduleId = data.ReadUint64();

    uint32_t templateIdsSize = data.ReadUint32();
    dataBlock.templateIds.reserve(templateIdsSize);
    for (uint32_t i0 = 0; i0 < templateIdsSize; ++i0) {
        uint64_t value0 = data.ReadUint64();
        dataBlock.templateIds.push_back(value0);
    }
    dataBlock.authType = (AuthType)data.ReadUint32();
    dataBlock.executorMatcher = data.ReadUint32();
    dataBlock.scheduleMode = (ScheduleMode)data.ReadUint32();

    uint32_t executorsSize = data.ReadUint32();
    dataBlock.executors.reserve(executorsSize);
    for (uint32_t i0 = 0; i0 < executorsSize; ++i0) {
        ExecutorInfo value0;
        if (!ExecutorInfoBlockUnmarshalling(data, value0)) {
            HDF_LOGE("%{public}s: read value0 failed!", __func__);
            return false;
        }
        dataBlock.executors.push_back(value0);
    }
    return true;
}

bool AuthSolutionBlockMarshalling(OHOS::MessageParcel& data, const AuthSolution& dataBlock)
{
    if (!data.WriteInt32(dataBlock.userId)) {
        HDF_LOGE("%{public}s: write dataBlock.userId failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.authTrustLevel)) {
        HDF_LOGE("%{public}s: write dataBlock.authTrustLevel failed!", __func__);
        return false;
    }

    if (!data.WriteUint32((uint32_t)dataBlock.authType)) {
        HDF_LOGE("%{public}s: write dataBlock.authType failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.executorSensorHint)) {
        HDF_LOGE("%{public}s: write dataBlock.executorSensorHint failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.challenge.size())) {
        HDF_LOGE("%{public}s: write dataBlock.challenge.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.challenge) {
        if (!data.WriteUint8(it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }
    return true;
}

bool AuthSolutionBlockUnmarshalling(OHOS::MessageParcel& data, AuthSolution& dataBlock)
{
    dataBlock.userId = data.ReadInt32();
    dataBlock.authTrustLevel = data.ReadUint32();
    dataBlock.authType = (AuthType)data.ReadUint32();
    dataBlock.executorSensorHint = data.ReadUint32();

    uint32_t challengeSize = data.ReadUint32();
    dataBlock.challenge.reserve(challengeSize);
    for (uint32_t i0 = 0; i0 < challengeSize; ++i0) {
        uint8_t value0 = data.ReadUint8();
        dataBlock.challenge.push_back(value0);
    }
    return true;
}

bool ExecutorSendMsgBlockMarshalling(OHOS::MessageParcel& data, const ExecutorSendMsg& dataBlock)
{
    if (!data.WriteUint64(dataBlock.executorIndex)) {
        HDF_LOGE("%{public}s: write dataBlock.executorIndex failed!", __func__);
        return false;
    }

    if (!data.WriteInt32(dataBlock.commandId)) {
        HDF_LOGE("%{public}s: write dataBlock.commandId failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.msg.size())) {
        HDF_LOGE("%{public}s: write dataBlock.msg.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.msg) {
        if (!data.WriteUint8(it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }
    return true;
}

bool ExecutorSendMsgBlockUnmarshalling(OHOS::MessageParcel& data, ExecutorSendMsg& dataBlock)
{
    dataBlock.executorIndex = data.ReadUint64();
    dataBlock.commandId = data.ReadInt32();

    uint32_t msgSize = data.ReadUint32();
    dataBlock.msg.reserve(msgSize);
    for (uint32_t i0 = 0; i0 < msgSize; ++i0) {
        uint8_t value0 = data.ReadUint8();
        dataBlock.msg.push_back(value0);
    }
    return true;
}

bool AuthResultInfoBlockMarshalling(OHOS::MessageParcel& data, const AuthResultInfo& dataBlock)
{
    if (!data.WriteInt32(dataBlock.result)) {
        HDF_LOGE("%{public}s: write dataBlock.result failed!", __func__);
        return false;
    }

    if (!data.WriteInt32(dataBlock.freezingTime)) {
        HDF_LOGE("%{public}s: write dataBlock.freezingTime failed!", __func__);
        return false;
    }

    if (!data.WriteInt32(dataBlock.remainTimes)) {
        HDF_LOGE("%{public}s: write dataBlock.remainTimes failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.msgs.size())) {
        HDF_LOGE("%{public}s: write dataBlock.msgs.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.msgs) {
        if (!ExecutorSendMsgBlockMarshalling(data, it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }

    if (!data.WriteUint32(dataBlock.token.size())) {
        HDF_LOGE("%{public}s: write dataBlock.token.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.token) {
        if (!data.WriteUint8(it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }

    if (!data.WriteUint32(dataBlock.rootSecret.size())) {
        HDF_LOGE("%{public}s: write dataBlock.rootSecret.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.rootSecret) {
        if (!data.WriteUint8(it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }
    return true;
}

bool AuthResultInfoBlockUnmarshalling(OHOS::MessageParcel& data, AuthResultInfo& dataBlock)
{
    dataBlock.result = data.ReadInt32();
    dataBlock.freezingTime = data.ReadInt32();
    dataBlock.remainTimes = data.ReadInt32();

    uint32_t msgsSize = data.ReadUint32();
    dataBlock.msgs.reserve(msgsSize);
    for (uint32_t i0 = 0; i0 < msgsSize; ++i0) {
        ExecutorSendMsg value0;
        if (!ExecutorSendMsgBlockUnmarshalling(data, value0)) {
            HDF_LOGE("%{public}s: read value0 failed!", __func__);
            return false;
        }
        dataBlock.msgs.push_back(value0);
    }

    uint32_t tokenSize = data.ReadUint32();
    dataBlock.token.reserve(tokenSize);
    for (uint32_t i0 = 0; i0 < tokenSize; ++i0) {
        uint8_t value0 = data.ReadUint8();
        dataBlock.token.push_back(value0);
    }

    uint32_t rootSecretSize = data.ReadUint32();
    dataBlock.rootSecret.reserve(rootSecretSize);
    for (uint32_t i0 = 0; i0 < rootSecretSize; ++i0) {
        uint8_t value0 = data.ReadUint8();
        dataBlock.rootSecret.push_back(value0);
    }
    return true;
}

bool IdentifyResultInfoBlockMarshalling(OHOS::MessageParcel& data, const IdentifyResultInfo& dataBlock)
{
    if (!data.WriteInt32(dataBlock.result)) {
        HDF_LOGE("%{public}s: write dataBlock.result failed!", __func__);
        return false;
    }

    if (!data.WriteInt32(dataBlock.userId)) {
        HDF_LOGE("%{public}s: write dataBlock.userId failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.token.size())) {
        HDF_LOGE("%{public}s: write dataBlock.token.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.token) {
        if (!data.WriteUint8(it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }
    return true;
}

bool IdentifyResultInfoBlockUnmarshalling(OHOS::MessageParcel& data, IdentifyResultInfo& dataBlock)
{
    dataBlock.result = data.ReadInt32();
    dataBlock.userId = data.ReadInt32();

    uint32_t tokenSize = data.ReadUint32();
    dataBlock.token.reserve(tokenSize);
    for (uint32_t i0 = 0; i0 < tokenSize; ++i0) {
        uint8_t value0 = data.ReadUint8();
        dataBlock.token.push_back(value0);
    }
    return true;
}

bool EnrollParamBlockMarshalling(OHOS::MessageParcel& data, const EnrollParam& dataBlock)
{
    if (!data.WriteUint32((uint32_t)dataBlock.authType)) {
        HDF_LOGE("%{public}s: write dataBlock.authType failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.executorSensorHint)) {
        HDF_LOGE("%{public}s: write dataBlock.executorSensorHint failed!", __func__);
        return false;
    }
    return true;
}

bool EnrollParamBlockUnmarshalling(OHOS::MessageParcel& data, EnrollParam& dataBlock)
{
    dataBlock.authType = (AuthType)data.ReadUint32();
    dataBlock.executorSensorHint = data.ReadUint32();
    return true;
}

bool CredentialInfoBlockMarshalling(OHOS::MessageParcel& data, const CredentialInfo& dataBlock)
{
    if (!data.WriteUint64(dataBlock.credentialId)) {
        HDF_LOGE("%{public}s: write dataBlock.credentialId failed!", __func__);
        return false;
    }

    if (!data.WriteUint64(dataBlock.executorIndex)) {
        HDF_LOGE("%{public}s: write dataBlock.executorIndex failed!", __func__);
        return false;
    }

    if (!data.WriteUint64(dataBlock.templateId)) {
        HDF_LOGE("%{public}s: write dataBlock.templateId failed!", __func__);
        return false;
    }

    if (!data.WriteUint32((uint32_t)dataBlock.authType)) {
        HDF_LOGE("%{public}s: write dataBlock.authType failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.executorMatcher)) {
        HDF_LOGE("%{public}s: write dataBlock.executorMatcher failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.executorSensorHint)) {
        HDF_LOGE("%{public}s: write dataBlock.executorSensorHint failed!", __func__);
        return false;
    }
    return true;
}

bool CredentialInfoBlockUnmarshalling(OHOS::MessageParcel& data, CredentialInfo& dataBlock)
{
    dataBlock.credentialId = data.ReadUint64();
    dataBlock.executorIndex = data.ReadUint64();
    dataBlock.templateId = data.ReadUint64();
    dataBlock.authType = (AuthType)data.ReadUint32();
    dataBlock.executorMatcher = data.ReadUint32();
    dataBlock.executorSensorHint = data.ReadUint32();
    return true;
}

bool EnrolledInfoBlockMarshalling(OHOS::MessageParcel& data, const EnrolledInfo& dataBlock)
{
    if (!data.WriteUint64(dataBlock.enrolledId)) {
        HDF_LOGE("%{public}s: write dataBlock.enrolledId failed!", __func__);
        return false;
    }

    if (!data.WriteUint32((uint32_t)dataBlock.authType)) {
        HDF_LOGE("%{public}s: write dataBlock.authType failed!", __func__);
        return false;
    }
    return true;
}

bool EnrolledInfoBlockUnmarshalling(OHOS::MessageParcel& data, EnrolledInfo& dataBlock)
{
    dataBlock.enrolledId = data.ReadUint64();
    dataBlock.authType = (AuthType)data.ReadUint32();
    return true;
}

bool EnrollResultInfoBlockMarshalling(OHOS::MessageParcel& data, const EnrollResultInfo& dataBlock)
{
    if (!data.WriteUint64(dataBlock.credentialId)) {
        HDF_LOGE("%{public}s: write dataBlock.credentialId failed!", __func__);
        return false;
    }

    if (!CredentialInfoBlockMarshalling(data, dataBlock.oldInfo)) {
        HDF_LOGE("%{public}s: write dataBlock.oldInfo failed!", __func__);
        return false;
    }

    if (!data.WriteUint32(dataBlock.rootSecret.size())) {
        HDF_LOGE("%{public}s: write dataBlock.rootSecret.size failed!", __func__);
        return false;
    }
    for (const auto& it0 : dataBlock.rootSecret) {
        if (!data.WriteUint8(it0)) {
            HDF_LOGE("%{public}s: write it0 failed!", __func__);
            return false;
        }
    }
    return true;
}

bool EnrollResultInfoBlockUnmarshalling(OHOS::MessageParcel& data, EnrollResultInfo& dataBlock)
{
    dataBlock.credentialId = data.ReadUint64();

    if (!CredentialInfoBlockUnmarshalling(data, dataBlock.oldInfo)) {
        HDF_LOGE("%{public}s: read dataBlock.oldInfo failed!", __func__);
        return false;
    }

    uint32_t rootSecretSize = data.ReadUint32();
    dataBlock.rootSecret.reserve(rootSecretSize);
    for (uint32_t i0 = 0; i0 < rootSecretSize; ++i0) {
        uint8_t value0 = data.ReadUint8();
        dataBlock.rootSecret.push_back(value0);
    }
    return true;
}

} // V1_0
} // UserAuth
} // HDI
} // OHOS
